package replicant3.replicant3;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.io.IOException;
import com.google.common.collect.ArrayListMultimap;

public class replica_pratik extends corbainterfacePOA {
	int port=0;
	String server=null;
	
	/*
	count 1 = Offline account at NA
    count 2 = Offline account at EU
    count 3 = Offline account at AS
	count 4 = Online account at NA
    count 5 = Online account at EU
    count 6 = Online account at AS   
    */
	
	static int count1=0,count2=0,count3=0,count4=0,count5=0,count6=0,x=0;
	
	
    public ArrayListMultimap<String,Object>  myMultimap = ArrayListMultimap.create();
    public ConcurrentHashMap<String,String> onlineentry = new ConcurrentHashMap<String,String>();
	
        
    protected replica_pratik(int portnumber) throws RemoteException
	{
		super();
		port=portnumber;
	}
	@Override
	public String createPlayerAccount(String FirstName, String LastName,
			String Age, String Username, String Password, String IPAddress) {
		if (IPAddress.startsWith("132")){count1 = count1 +1 ;}
	   	 else if (IPAddress.startsWith("93")){count2 = count2 +1 ;}
		 else {count3 = count3 +1 ;}
			
			String pass = "1";
			String fail = "0";
			final Object lock = new Object();
		try{
				synchronized(lock){
					
			if (!myMultimap.containsKey(Username)){
						myMultimap.put(Username, FirstName);
						myMultimap.put(Username, LastName);
						myMultimap.put(Username, Age);
						myMultimap.put(Username, Username);
						myMultimap.put(Username, Password);
				        myMultimap.put(Username, IPAddress);
				       
				      
				   } else {

					   return fail ; }
			
				}
		}
			catch(Exception e)
			{
				e.printStackTrace();
			}
	
			return pass;

	}
	@Override
	public String playerSignIn(String Username, String Password,
			String IPAddress) {
		String pass = "1";
		String fail = "0";
        if (myMultimap.containsKey(Username)){
        	if(myMultimap.containsValue(Password)){
        		if(onlineentry.get(Username) == null){
        			if (IPAddress.startsWith("132")){
        		onlineentry.put(Username,IPAddress);}
        			else if (IPAddress.startsWith("93")){
                		onlineentry.put(Username,IPAddress);}
        			else {
                		onlineentry.put(Username,IPAddress);}
        		if (IPAddress.startsWith("132")){count4 = count4 +1 ;}
           	 else if (IPAddress.startsWith("93")){count5 = count5 +1 ;}
           	 else {count6 = count6 +1 ;}


        		return pass;
        		
        		}
        		else { return fail; }
        		}else {

        			return fail;}
        }else{

        	return fail ;
        	
        }
	}

	@Override
	public String playerSignOut(String Username, String IPAddress) {
		String pass = "1";
		String fail = "0";
        
        if(onlineentry.containsKey(Username)){
        	
        	if(onlineentry.containsValue(IPAddress)){	 
       	 onlineentry.remove(Username);
        			 count4 = count4 - 1 ;
 
                    return pass ;
        		}else{

                    return fail ;
        			
        		}
        	
           
        }else{
  
            return fail ;
           }
       
	}
	public synchronized int getlocalCountonline()
 	{
 		int noOfRecords = 0;
 		noOfRecords =onlineentry.size() ;

 		return noOfRecords ;
 		
 	}
	
	 public synchronized void increase(String name, String pass){
        onlineentry.put(name, pass);
       
	}
	 public synchronized int getlocalCountoffline()
 	{
 		if (port == 5789){
	  		 x =count1 - count4;
	  		}
		if (port == 5799){
	  		 x =count2 - count5;
	  		}
		if (port == 6000){
	  		 x =count3 - count6;
	  		}

	return x;
 	}
	@Override
	public String getPlayerStatus(String Username, String Password,
			String IPAddress) {
		String Server1 = null,Server2 = null;
		int ServerPort1=0,ServerPort2=0;
		if (IPAddress.startsWith("132"))
			{
				server="NA";
				Server1 = "EU";
				Server2 = "AS";
				ServerPort1 = 5799;
				ServerPort2 = 6000;
	
			}
		else if (IPAddress.startsWith("93"))
		{
			server = "EU";
			Server1 = "NA";
			Server2 = "AS";
			ServerPort1 = 5789;
			ServerPort2 = 6000;
	
		}
		else
		{
			server = "AS";
			Server1 = "NA";
			Server2 = "EU";
			ServerPort1 = 5789;
			ServerPort2 = 5799;
	
			}
		String i,i2;
		int OfflineRecords;
		int OnlinenoOfRecords;
		OfflineRecords = getlocalCountoffline();
		OnlinenoOfRecords = getlocalCountonline();
		System.out.println(" ");
	
	i =	sendUDP_request(Server1, ServerPort1, Server2, ServerPort2);
	i2 =	sendUDP_request(Server2, ServerPort2, Server1, ServerPort1);
		String result;
		result = server+":"+OnlinenoOfRecords+":"+OfflineRecords;
		return result+";"+i+";"+i2+";";
	}
	public String sendUDP_request(String Server1 , int ServerPort1, String Server2, int ServerPort2)
	{
		String u=null;
		int [] portNumbers = new int[]{ServerPort1,ServerPort2};
		for(int i =0; i<2;i++)
		{
			DatagramSocket clientSocket = null;
			try{
				clientSocket = new DatagramSocket();
				byte [] serverInfo = (Server1+ServerPort1).getBytes();
				InetAddress IP = InetAddress.getByName("localhost");
				DatagramPacket request = new DatagramPacket(serverInfo, serverInfo.length,IP,portNumbers[i]);
				clientSocket.send(request);
				byte [] ServerCount = new byte[1024];
				DatagramPacket reply = new DatagramPacket(ServerCount,ServerCount.length);
				clientSocket.receive(reply);
				
			u =	new String(reply.getData()).trim();
				
			}catch(SocketException e){System.out.println("Socket:" +e.getMessage());
			}catch(IOException e){ System.out.println("IO: "+e.getMessage());
			}finally {if(clientSocket != null)clientSocket.close(); }
		}
		return u;
	}
	
	private void sendUDP_requests(String Server1 , int ServerPort1,String UserName)
	{
		
			DatagramSocket clientSocket = null;
			try{
				String finalString = ""; 
				String Data[]= {"FirstName","LastName","Age","UserName","Password","IPAddress"}; 
				List<Object> array = myMultimap.get(UserName) ;
				System.out.println("ArraySize" + array.size());
				
				for(int i = 0 ; i < array.size() ; i++){
				
					finalString = finalString + Data[i] + ":" ;
					finalString = finalString +  array.get(i);
					
					if(i< array.size()- 1)
					finalString = finalString + "," ;
					
				}
				
				clientSocket = new DatagramSocket();
				byte [] serverInfo = finalString.getBytes() ;
				InetAddress IP = InetAddress.getByName("localhost");
				DatagramPacket request = new DatagramPacket(serverInfo, serverInfo.length,IP,ServerPort1);
				clientSocket.send(request);
				byte [] ServerCount = new byte[1024];
				DatagramPacket reply = new DatagramPacket(ServerCount,ServerCount.length);
				clientSocket.receive(reply);
			}catch(SocketException e){System.out.println("Socket:" +e.getMessage());
			}catch(IOException e){ System.out.println("IO: "+e.getMessage());
			}finally {if(clientSocket != null)clientSocket.close(); }
		
	}
	@Override
	public String transferAccount(String Username, String Password,
			String OldIPAddress, String NewIPAddress) {
		String pass = "1";
		String fail = "0";
	if(NewIPAddress.startsWith("132")){
			sendUDP_requests("North",5789,Username);
			count1++;
			count4++;
			
		}else if(NewIPAddress.startsWith("93")){
			sendUDP_requests("Europe",5799,Username);
			count2++;
			count5++;
			
		}
		else  if(NewIPAddress.startsWith("182")){
			count3++;
			if(onlineentry.containsKey(Username) && onlineentry.containsValue(NewIPAddress)){
			
			count6++;
				}
			sendUDP_requests("Asia",6000,Username);
			

		}
		else{
			return fail;
		}
		if(OldIPAddress.startsWith("132")){
			 count1 = count1 - 1;
  	  		 count4 = count4 - 1;
  	  		
		}
		else if(OldIPAddress.startsWith("93")){
			count2 = count2 - 1;
	  		 count5 = count5 - 1;
	  		
		}
		else if(OldIPAddress.startsWith("182")){
			count3 = count3 - 1;
  	  		count6 = count6 - 1 ;
  	  				}
		else {
			return fail;
		}
		
	
	    myMultimap.removeAll(Username) ;
	
		onlineentry.remove(Username);

		return pass;
	}

	@Override
	public String suspendAccount(String AdminUsername, String AdminPassword,
			String AdminIP, String UsernameToSuspend) {
		String pass = "1";
		String fail = "0";

		if(onlineentry.containsKey(UsernameToSuspend))
	{
			count6--;
					  }
		
		
		
		if(myMultimap.containsEntry(UsernameToSuspend,"182.32.32.32")){
		count3--;
		}
	
		if(myMultimap.containsEntry(UsernameToSuspend,"93.32.32.32")){
			count2--;
			}
		
		else{
			count1--;
			}
		 if (myMultimap.containsKey(UsernameToSuspend)){
			 myMultimap.removeAll(UsernameToSuspend) ;
			 onlineentry.remove(UsernameToSuspend);
			 
		 }
		 else{
				return fail;
		}

		
		return  pass;
	}

}
